home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-19 | 95.9 KB | 2,770 lines | [TEXT/CWIE] |
- /*
- File: MoreAEM.c
-
- Contains: C++ wrappers for the AppleEvent Manager
-
- Written by: Greg Anderson
-
- Copyright: © 1992-1996 by Apple Computer, Inc., all rights reserved.
-
- <31> 2/15/95 ga
-
- */
-
- #ifdef MWTRACEBACKTABLES
- #pragma traceback on
- #endif
-
- #include "MoreAEM.h"
-
- #include <AppleEvents.h>
- #include <AERegistry.h>
- #include <Errors.h>
-
- #include <AEPackObject.h>
- #include <AEObjects.h>
- #include <ASRegistry.h>
-
- // #include "FinderRegistry.h"
-
- #include "Exceptions.h"
- #include "Debug.h"
-
-
-
- #pragma segment AEMStuff
-
-
- MakeTokenDescriptorProcPtr gNullContainerCreationProc = nil;
- ProcessDescriptorProcPtr gPreResolveProc = nil;
- MergeTokensProcPtr gMergeTokensProc = nil;
-
- SInt16 TDescriptor::fCallbackFlags = kAEIDoMinimum;
-
- #define kDayLengthInSecs (24*60*60)
-
-
- //================================================================================
- // Class TStringCompareBehavior
- //================================================================================
-
- class TStringCompareBehavior : public TAbstractCompareBehavior
- {
- virtual CompareEnumeration CompareDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const;
- virtual Boolean ContainsDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const;
-
- static Boolean IsTextType(DescType theType);
- };
-
- //----------------------------------------------------------------------------------------
- // TStringCompareBehavior::IsTextType
- //----------------------------------------------------------------------------------------
- Boolean TStringCompareBehavior::IsTextType(DescType theType)
- {
- return (theType == typeAEText) || (theType == typeIntlText) || (theType == typeStyledText) || (theType == typeChar);
- }
-
- //----------------------------------------------------------------------------------------
- // TStringCompareBehavior::CompareDynamicBehavior
- //----------------------------------------------------------------------------------------
- CompareEnumeration TStringCompareBehavior::CompareDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
- {
- CompareEnumeration compareResult = kObjectKeysEqual;
-
- //
- // We can compare any sort of textual objects; anything that isn't
- // text will have to be handled by some other comparitor.
- //
- if(IsTextType(object1.DataType()) && IsTextType(object2.DataType()))
- {
- TConstDataReference object1Data(object1);
- TConstDataReference object2Data(object2);
- TDescriptor tempObject1Desc;
- TDescriptor tempObject2Desc;
-
- //
- // First, coerce the data to be a simple typeChar
- // (International note: we loose information such
- // as the script code when we do this. This routine
- // is NOT a good example of how to compare text).
- //
- if(object1.DataType() != typeChar)
- {
- FailErr(AECoercePtr(object1.DataType(), object1.Data(), object1.DataLength(), typeChar, tempObject1Desc));
- tempObject1Desc.Lock();
- object1Data = TConstDataReference(tempObject1Desc);
- }
- if(object2.DataType() != typeChar)
- {
- FailErr(AECoercePtr(object2.DataType(), object2.Data(), object2.DataLength(), typeChar, tempObject2Desc));
- tempObject2Desc.Lock();
- object2Data = TConstDataReference(tempObject2Desc);
- }
-
- //
- // Now that we have two strings of typeChar, compare them
- //
- SInt32 compareLength = object1Data.DataLength() < object2Data.DataLength() ? object1Data.DataLength() : object2Data.DataLength();
- const char* data = object1Data.Data();
- const char* compareWith = object2Data.Data();
-
- for(SInt32 i=0; i < compareLength; ++i)
- {
- unsigned char compareWithChar = *((unsigned char*)compareWith);
- unsigned char dataChar = *((unsigned char*)data);
-
- if((compareWithChar >= 'a') && (compareWithChar <= 'z'))
- compareWithChar = compareWithChar - 'a' + 'A';
- if((dataChar >= 'a') && (dataChar <= 'z'))
- dataChar = dataChar - 'a' + 'A';
-
- if(compareWithChar > dataChar)
- {
- compareResult = kSecondObjectComesAfter;
- break;
- }
- else if(compareWithChar < dataChar)
- {
- compareResult = kSecondObjectComesBefore;
- break;
- }
- ++compareWith;
- ++data;
- }
-
- //
- // If the first 'compareLength' bytes of the data stream are equal, then
- // equality is based on the lengths of the strings
- //
- if(compareResult == kObjectKeysEqual)
- {
- if(object2Data.DataLength() > object1Data.DataLength())
- compareResult = kSecondObjectComesAfter;
- if(object2Data.DataLength() < object1Data.DataLength())
- compareResult = kSecondObjectComesBefore;
- }
-
- //
- // Delete our temporary data, if we allocated it.
- //
- tempObject1Desc.Dispose();
- tempObject2Desc.Dispose();
- }
- else
- {
- compareResult = TAbstractCompareBehavior::CompareDynamicBehavior(object1, object2);
- }
-
- return compareResult;
- }
-
- //----------------------------------------------------------------------------------------
- // TStringCompareBehavior::ContainsDynamicBehavior
- //----------------------------------------------------------------------------------------
- Boolean TStringCompareBehavior::ContainsDynamicBehavior(const TAbstractDataReference& object1, const TAbstractDataReference& object2) const
- {
- Boolean containsResult = false;
-
- //
- // We can compare any sort of textual objects; anything that isn't
- // text will have to be handled by some other comparitor.
- //
- if(IsTextType(object1.DataType()) && IsTextType(object2.DataType()))
- {
- TConstDataReference object1Data(object1);
- TConstDataReference object2Data(object2);
- TDescriptor tempObject1Desc;
- TDescriptor tempObject2Desc;
-
- //
- // ◊Move these compare routines to MoreStrings, and make them use the cooler string-compare functions.
- //
- // First, coerce the data to be a simple typeChar
- // (International note: we loose information such
- // as the script code when we do this. This routine
- // is NOT a good example of how to compare text).
- //
- if(object1.DataType() != typeChar)
- {
- FailErr(AECoercePtr(object1.DataType(), object1.Data(), object1.DataLength(), typeChar, tempObject1Desc));
- object1Data = TConstDataReference(tempObject1Desc);
- }
- if(object2.DataType() != typeChar)
- {
- FailErr(AECoercePtr(object2.DataType(), object2.Data(), object2.DataLength(), typeChar, tempObject2Desc));
- object2Data = TConstDataReference(tempObject1Desc);
- }
-
- //
- // Look for object2 inside of object1
- //
- SInt32 lengthDifference = object1.DataLength() - object2.DataLength();
- const char* data = object1.Data();
-
- while(lengthDifference >= 0)
- {
- TConstDataReference partialString(object1.DataType(), data, object2.DataLength());
-
- if(partialString.Compare(object2) == kObjectKeysEqual)
- {
- containsResult = true;
- break;
- }
-
- --lengthDifference;
- ++data;
- }
-
- //
- // Delete our temporary data, if we allocated it.
- //
- tempObject1Desc.Dispose();
- tempObject2Desc.Dispose();
- }
- else
- {
- containsResult = TAbstractCompareBehavior::ContainsDynamicBehavior(object1, object2);
- }
-
- return containsResult;
- }
-
- //----------------------------------------------------------------------------------------
- // InstallStringCompareBehavior
- //
- // Add our cheezy roman-only string compare behavior
- //----------------------------------------------------------------------------------------
- void InstallStringCompareBehavior()
- {
- TStringCompareBehavior* compareBehavior = new TStringCompareBehavior;
-
- TAbstractDataReference::AddCompareBehavoir(compareBehavior);
- }
-
- //----------------------------------------------------------------------------------------
- // InstallNullContainerCreationProc:
- //
- // The null container creation proc is used by TDescriptor::Resolve whenever it receives
- // a null descriptor to resolve. This function is used to create a token for the null
- // container.
- //----------------------------------------------------------------------------------------
- void InstallNullContainerCreationProc(MakeTokenDescriptorProcPtr creationProc)
- {
- gNullContainerCreationProc = creationProc;
- } // InstallNullContainerCreationProc
-
- //----------------------------------------------------------------------------------------
- // InstallPreResolveProc:
- //
- // The PreResolveProc is called by TDescriptor::Resolve before it actually calls
- // AEResolve. This allows special procs to handle things not understood by AEResolve
- // (alias records, for example).
- //----------------------------------------------------------------------------------------
- void InstallPreResolveProc(ProcessDescriptorProcPtr preResolveProc)
- {
- gPreResolveProc = preResolveProc;
- } // InstallPreResolveProc
-
- //----------------------------------------------------------------------------------------
- // InstallMergeTokensProc:
- //
- // The MergeTokensProc is called by TTokenDescriptor::AdoptToken whenever it needs to add
- // a token object to any token descriptor that already contains a token. The merge token
- // proc is provided with two TAbstractScriptableObject*'s; it must return a
- // TAbstractScriptableObject* that has adopted the two tokens passed to it.
- //----------------------------------------------------------------------------------------
- void InstallMergeTokensProc(MergeTokensProcPtr mergeTokensProc)
- {
- gMergeTokensProc = mergeTokensProc;
- } // InstallMergeTokensProc
-
- //----------------------------------------------------------------------------------------
- // CreateNullContainerToken:
- //----------------------------------------------------------------------------------------
- TTokenDescriptor CreateNullContainerToken()
- {
- TTokenDescriptor nullContainer;
-
- if(gNullContainerCreationProc != nil)
- nullContainer = (*gNullContainerCreationProc)();
-
- return nullContainer;
- } // CreateNullContainerToken
-
- //========================================================================================
- // CLASS TDescriptor
- //
- // Class TDescriptor is a wrapper class for AEDesc objects.
- //========================================================================================
-
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Descriptor memory management:
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Dispose:
- //
- // Disposed of the descriptor and the data stored inside it. TDescriptors must be
- // disposed explicitly: they are NOT disposed in their destructor.
- //----------------------------------------------------------------------------------------
- void TDescriptor::Dispose()
- {
- FailErr(AEDisposeDesc(*this));
- } // TDescriptor::Dispose
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Clone:
- //
- // Return an exact copy of this descriptor
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::Clone() const
- {
- TDescriptor clonedDescriptor;
-
- clonedDescriptor.SetDescriptorData(*this);
-
- return clonedDescriptor;
- } // TDescriptor::Clone
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AdoptDescriptor:
- //----------------------------------------------------------------------------------------
- void TDescriptor::AdoptDescriptor(TDescriptor& desc)
- {
- fAEDesc = desc;
- desc.ClearDescriptor();
- } // TDescriptor::AdoptDescriptor
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Comparison methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Compare:
- //
- // Compare two descriptors. ComparisonOperator should be one of the following:
- //
- // kAEEquals, kASNotEqual, kAEGreaterThan, kAEGreaterThanEquals, kAELessThan,
- // kASLessThanOrEqual, kAEBeginsWith, kAEEndsWith, or kAEContains
- //----------------------------------------------------------------------------------------
- Boolean TDescriptor::Compare(DescType comparisonOperator, const TDescriptor& compareWith) const
- {
- Boolean compareResult = false;
-
- //
- // It might be nice to try to do a type coercion here, but for now
- // we only compare descriptors of the same type
- //
- if(this->DescriptorType() != compareWith.DescriptorType())
- FailErr(errAEEventNotHandled);
-
- return CompareTypedData(comparisonOperator, *this, compareWith);
- } // TDescriptor::Compare
-
-
- //----------------------------------------------------------------------------------------
- // ReverseComparisonOperator:
- //
- // Sometimes it cannot be avoided: we must convert from "a compareisonOp b" to
- // "b reverseComparisonOp a". This routine determines what the reverse operation
- // should be.
- //----------------------------------------------------------------------------------------
- DescType ReverseComparisonOperator(DescType comparisonOperator)
- {
- DescType result = comparisonOperator;
-
- switch(comparisonOperator)
- {
- case kAEEquals:
- case kASNotEqual:
- {
- result = comparisonOperator;
- }
- break;
-
- case kAEGreaterThan:
- {
- result = kAELessThan;
- }
- break;
-
- case kAEGreaterThanEquals:
- {
- result = kAELessThanEquals;
- }
- break;
-
- case kAELessThan:
- {
- result = kAEGreaterThan;
- }
- break;
-
- case kAELessThanEquals:
- {
- result = kAEGreaterThanEquals;
- }
- break;
-
- case kAEBeginsWith:
- {
- result = kAEAtTheBeginningOf;
- }
- break;
-
- case kAEEndsWith:
- {
- result = kAEAtTheEndOf;
- }
- break;
-
- case kAEContains:
- {
- result = kAEIsContainedIn;
- }
- break;
-
- case kAEAtTheBeginningOf:
- {
- result = kAEBeginsWith;
- }
- break;
-
- case kAEAtTheEndOf:
- {
- result = kAEEndsWith;
- }
- break;
-
- case kAEIsContainedIn:
- {
- result = kAEContains;
- }
- break;
-
- //
- // ◊Script: We should fail if we don't recognize the comparison operator
- //
- default:
- {
- result = 0;
- }
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // InterpretCompareResult:
- //
- // Given two keys and a comparison opperator, this function determines if
- // the comparison between key2 and key1 is true or false. key1 and key2 should
- // be either two long integers representing the various values of the two descriptors
- // being compared, or key1 may be set to 0 and key2 set to -1 (key2 < key1), 0
- // (key1 == key2) or 1 (key2 > key1).
- //
- // This function is used by GeneralCompare, which is used by TDescriptor::Compare
- //----------------------------------------------------------------------------------------
- Boolean InterpretCompareResult(DescType comparisonOperator, SInt32 key1, SInt32 key2 )
- {
- switch(comparisonOperator)
- {
- case kAEEquals:
- {
- return key1 == key2;
- }
-
- case kASNotEqual:
- {
- return key1 != key2;
- }
-
- case kAEGreaterThan:
- {
- return key1 > key2;
- }
-
- case kAEGreaterThanEquals:
- {
- return key1 >= key2;
- }
-
- case kAELessThan:
- {
- return key1 < key2;
- }
-
- case kAELessThanEquals:
- {
- return key1 <= key2;
- }
-
- //
- // ••• Perhaps we should fail if we don't recognize the comparisonOperator
- //
- default:
- {
- return false;
- }
- }
- } // InterpretCompareResult
-
- //----------------------------------------------------------------------------------------
- // CompareTypedData
- //----------------------------------------------------------------------------------------
- Boolean CompareTypedData(DescType comparisonOperator, const TAbstractDataReference& compareThisRef, const TAbstractDataReference& compareWithRef)
- {
- Boolean compareResult = false;
-
- switch(comparisonOperator)
- {
- case kAEEquals:
- case kASNotEqual:
- case kAEGreaterThan:
- case kAEGreaterThanEquals:
- case kAELessThan:
- case kASLessThanOrEqual:
- {
- compareResult = InterpretCompareResult(comparisonOperator, compareThisRef.Compare(compareWithRef), 0 );
- break;
- }
-
- //
- // Question: is this begins-with clipping bogus?
- //
- case kAEBeginsWith:
- {
- if(compareWithRef.DataLength() > compareThisRef.DataLength())
- compareResult = false;
- else
- {
- TConstDataReference beginningOfThis(compareThisRef.DataType(), compareThisRef.Data(), compareWithRef.DataLength());
- compareResult = InterpretCompareResult(kAEEquals, beginningOfThis.Compare(compareWithRef), 0 );
- }
- break;
- }
-
- //
- // Question: is this ends-with clipping bogus?
- //
- case kAEEndsWith:
- {
- SInt32 sizeDifference = compareThisRef.DataLength() - compareWithRef.DataLength();
- if(sizeDifference < 0)
- compareResult = false;
- else
- {
- TConstDataReference endOfThis(compareThisRef.DataType(), compareThisRef.Data() + sizeDifference, compareWithRef.DataLength());
- compareResult = InterpretCompareResult(kAEEquals, endOfThis.Compare(compareWithRef), 0 );
- }
- break;
- }
-
- case kAEContains:
- {
- compareResult = compareThisRef.Contains(compareWithRef);
- break;
- }
-
- case kAEAtTheBeginningOf:
- {
- compareResult = CompareTypedData(kAEBeginsWith, compareWithRef, compareThisRef);
- break;
- }
-
- case kAEAtTheEndOf:
- {
- compareResult = CompareTypedData(kAEEndsWith, compareWithRef, compareThisRef);
- break;
- }
-
- case kAEIsContainedIn:
- {
- compareResult = compareWithRef.Contains(compareThisRef);
- break;
- }
-
- default:
- {
- FailErr(errAEEventNotHandled);
- break;
- }
- }
-
- return compareResult;
- } // CompareTypedData
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Canonical get and set data accessors
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetDescriptorData
- //----------------------------------------------------------------------------------------
- void TDescriptor::GetDescriptorData(TUpdataDataReference& buffer, DescType typeToCoerceTo /*= typeWildCard*/) const
- {
- if(this->DataHandle())
- {
- if((typeToCoerceTo == typeWildCard) || (this->DescriptorType() == typeToCoerceTo))
- {
- //
- // Don't be tempted to use our operator TDescriptorDataReference to do
- // a simple buffer.CopyFrom(*this), because when buffer.CopyFrom invokes
- // TDescriptorDataReference::CopyTo, CopyTo will call this routine and
- // you'll never get out of the loop.
- //
- TConstDataReference inlineDataReference(this->DescriptorType(), *this->DataHandle(), this->DataSize());
- buffer.CopyFrom(inlineDataReference, true);
- }
- else
- {
- TDescriptor coercedData = Coerce(typeToCoerceTo);
- coercedData.GetDescriptorData(buffer);
- coercedData.Dispose();
- }
- }
- } // TDescriptor::GetDescriptorData
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetDescriptorData:
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetDescriptorData(const TAbstractDataReference& data, DescType typeToCoerceTo /*= typeWildCard*/)
- {
- if((typeToCoerceTo == typeWildCard) || (data.DataType() == typeToCoerceTo))
- FailErr(AECreateDesc(data.DataType(), (const Ptr)data.Data(), data.DataLength(), *this));
- else
- FailErr(AECoercePtr(data.DataType(), (const Ptr)data.Data(), data.DataLength(), typeToCoerceTo, *this));
- } // TDescriptor::SetDescriptorData
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetDescriptorData:
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetDescriptorData(const TDescriptor& desc)
- {
- FailErr(AEDuplicateDesc(desc, *this));
- } // TDescriptor::SetDescriptorData
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Data coercion
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AttemptToCoerce:
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::AttemptToCoerce(DescType typeToCoerceTo, OSErr& err) const
- {
- TDescriptor coercedDescriptor;
-
- err = AECoerceDesc(*this,typeToCoerceTo,coercedDescriptor);
-
- return coercedDescriptor;
- } // TDescriptor::AttemptToCoerce
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Coerce:
- //
- // Require that this object be coerced to the specified data type. This method will
- // fail if the coercion does not work.
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::Coerce(DescType typeToCoerceTo) const
- {
- TDescriptor coercedDescriptor;
-
- FailErr(AECoerceDesc(*this,typeToCoerceTo,coercedDescriptor));
-
- return coercedDescriptor;
- } // TDescriptor::Coerce
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AttemptCoerceInPlace:
- //
- // Try to coerce the type of the descriptor to something else. This method will
- // NOT fail if the coercion could not be done.
- //----------------------------------------------------------------------------------------
- OSErr TDescriptor::AttemptCoerceInPlace(DescType typeToCoerceTo)
- {
- OSErr err = noErr;
-
- if(this->DescriptorType() != typeToCoerceTo)
- {
- #if 1
- err = AECoerceDesc(*this,typeToCoerceTo, *this);
- #else //◊
- //
- // This way works, but the data handle of this descriptor
- // is disposed an replaced with a new copy. This isn't
- // so hot if you have a copy of an AEDesc that you'd like
- // to coerce that someone else is going to dispose later.
- //
- // In short, preserveHandle == kAllowHandleReallocation is
- // faster, but more dangerous.
- //
- if(preserveHandle == kAllowHandleReallocation)
- err = AECoerceDesc(*this,typeToCoerceTo, *this);
- else
- {
- TDescriptor tempDescriptor;
-
- // If AECoerceDesc returns a non-zero result code, then
- // tempDescriptor will be typeNull, and we don't need to
- // worry about disposing of it.
- err = AECoerceDesc(*this,typeToCoerceTo, tempDescriptor);
-
- if(err == noErr)
- {
- Try
- {
- Handle initialHandle = this->DataHandle();
- Handle coercedHandle = tempDescriptor.DataHandle();
-
- //
- // If doing a coerce-in-place, try to do a SetHandleSize
- // and then a BlockMove so that we end up using the same
- // handle when we exit as we had when we entered. To do
- // otherwise is to invite double-dispose/memory leak problems
- // if some other peice of code still has a reference to
- // the descriptor before it was coerced
- //
- if((initialHandle != nil) && (coercedHandle != nil))
- {
- Size coercedSize = GetHandleSize(coercedHandle);
- SetHandleSize(initialHandle, coercedSize);
- FailErr(MemError());
- BlockMoveData(*coercedHandle, *initialHandle, coercedSize);
- this->fDescriptorType = tempDescriptor.DescriptorType();
- tempDescriptor.Dispose();
- }
- //
- // There are a couple of rare cases (typeTrue and typeFalse)
- // where the data handle is nil
- //
- else
- {
- //
- // It's undesirable to go from a nil-handle to a non-nil
- // handle, or visa-versa. Don't do it. Use 'Coerce'
- // rather than 'CoerceInPlace' if this is necessary.
- //
- if((initialHandle != nil) || (coercedHandle != nil))
- ASSERTPRINT(false, ("Potentially undesirable coerce-in-place"));
- //
- // Try to dispose of the old descriptor (ignoring errors)
- // and then plug in the values from the coerced descriptor
- //
- AEDisposeDesc(*this);
- this->AdoptDescriptor(tempDescriptor);
- }
- }
- Catch(err)
- {
- tempDescriptor.Dispose();
- }
- }
- }
- #endif
- }
-
- return err;
- } // TDescriptor::AttemptCoerceInPlace
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::CoerceInPlace:
- //
- // Require that this object be coerced to the specified data type. This method will
- // fail if the coercion does not work.
- //----------------------------------------------------------------------------------------
- void TDescriptor::CoerceInPlace(DescType typeToCoerceTo)
- {
- FailErr(this->AttemptCoerceInPlace(typeToCoerceTo));
- } // TDescriptor::CoerceInPlace
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: A multitude of ways to get descriptor data
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetBooleanData
- //----------------------------------------------------------------------------------------
- Boolean TDescriptor::GetBooleanData() const
- {
- Boolean result = 0;
-
- this->GetDescriptorData(TUpdataDataReference(typeBoolean, (char*)&result, sizeof(Boolean), sizeof(Boolean)), typeBoolean);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetSInt32Data
- //----------------------------------------------------------------------------------------
- SInt32 TDescriptor::GetSInt32Data() const
- {
- SInt32 result = 0;
-
- this->GetDescriptorData(TUpdataDataReference(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32)), typeSInt32);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetUInt32Data
- //----------------------------------------------------------------------------------------
- UInt32 TDescriptor::GetUInt32Data() const
- {
- UInt32 result = 0;
-
- this->GetDescriptorData(TUpdataDataReference(typeUInt32, (char*)&result, sizeof(UInt32), sizeof(UInt32)), typeUInt32);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetSInt64Data
- //----------------------------------------------------------------------------------------
- SInt64 TDescriptor::GetSInt64Data() const
- {
- SInt64 result;
-
- this->GetDescriptorData(TUpdataDataReference(typeSInt64, (char*)&result, sizeof(SInt64), sizeof(SInt64)), typeSInt64);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetDescTypeData
- //----------------------------------------------------------------------------------------
- DescType TDescriptor::GetDescTypeData(DescType expectedType /*= typeType*/) const
- {
- DescType result = 0;
-
- this->GetDescriptorData(TUpdataDataReference(expectedType, (char*)&result, sizeof(DescType), sizeof(DescType)), expectedType);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetPSNData
- //----------------------------------------------------------------------------------------
- ProcessSerialNumber TDescriptor::GetPSNData() const
- {
- ProcessSerialNumber result;
-
- this->GetDescriptorData(TUpdataDataReference(typeProcessSerialNumber, (char*)&result, sizeof(ProcessSerialNumber), sizeof(ProcessSerialNumber)), typeProcessSerialNumber);
-
- return result;
- }
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: A multitude of ways to set descriptor data
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetBooleanData
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetBooleanData(const Boolean& data)
- {
- this->SetDescriptorData(TConstDataReference(typeBoolean, (char*)&data, sizeof(Boolean)));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetSInt32Data
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetSInt32Data(const SInt32& data)
- {
- this->SetDescriptorData(TConstDataReference(typeSInt32, (char*)&data, sizeof(SInt32)));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetUInt32Data
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetUInt32Data(const UInt32& data)
- {
- this->SetDescriptorData(TConstDataReference(typeUInt32, (char*)&data, sizeof(UInt32)));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetSInt64Data
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetSInt64Data(const SInt64& data)
- {
- this->SetDescriptorData(TConstDataReference(typeSInt64, (char*)&data, sizeof(SInt64)));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetDescTypeData
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetDescTypeData(const SInt32& data, DescType dataType /*= typeType*/)
- {
- this->SetDescriptorData(TConstDataReference(dataType, (char*)&data, sizeof(DescType)));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetPSNData
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetPSNData(const ProcessSerialNumber& psn)
- {
- this->SetDescriptorData(TConstDataReference(typeProcessSerialNumber, (char*)&psn, sizeof(ProcessSerialNumber)));
- }
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: List methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::CreateList:
- //
- // Create an empty descriptor list or AERecord with factored data. The default
- // parameters cause this routine to create an empty list with no factored data.
- //----------------------------------------------------------------------------------------
- void TDescriptor::CreateList(Boolean isRecord, Ptr factoringPtr, Size factoredSize)
- {
- FailErr(AECreateList(factoringPtr, factoredSize, isRecord, *this));
- } // TDescriptor::CreateList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::CoerceToList:
- //
- // If this descriptor is null, an empty list is created. If this descriptor is not
- // empty, then a list is created and this descriptor is placed inside it. If this
- // descriptor is already a list, then no action is taken.
- //----------------------------------------------------------------------------------------
- void TDescriptor::CoerceToList()
- {
- if(this->IsNullDescriptor())
- {
- this->CreateList();
- }
- else if(this->DescriptorType() != typeAEList)
- {
- this->CoerceInPlace(typeAEList);
- }
- } // TDescriptor::CoerceToList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::CountItems:
- //
- // Count the items in a descriptor list. If this descriptor is not of typeAEList, then it
- // only has one item, and if the descriptor is null, then it has no items.
- //----------------------------------------------------------------------------------------
- UInt32 TDescriptor::CountItems() const
- {
- UInt32 items = 1;
- if(this->IsNullDescriptor())
- items = 0;
- else if((this->DescriptorType() == typeAEList) || (this->DescriptorType() == typeAERecord))
- FailErr(AECountItems(*this, (SInt32*)&items));
- return items;
- } // TDescriptor::CountItems
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetNthItem:
- //
- // Get the indexed descriptor from an event. This method will fail if given an index
- // less than one or greater than the count returned by TDescriptor::CountItems.
- // The descriptor returned is _always_ a copy that must be disposed of with
- // TDescriptor::Dispose.
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::GetNthItem(SInt32 index, DescType desiredType, AEKeyword* key) const
- {
- TDescriptor descriptor;
- AEKeyword ignoreKey;
-
- if(key == nil)
- key = &ignoreKey;
-
- //
- // We can "GetNthItem" on an item that is not of typeAEList
- // if the index is one; we do this by cloning ourself
- // (n.b. AERecords are also lists)
- //
- if((DescriptorType() != typeAEList) && (DescriptorType() != typeAERecord))
- {
- if(index != 1)
- FailErr(errAEIllegalIndex);
-
- *key = typeWildCard;
- descriptor = this->Clone();
- }
- else
- {
- FailErr(AEGetNthDesc(*this, index, desiredType, key, descriptor));
- }
-
- return descriptor;
- } // TDescriptor::GetNthItem
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetNthItemData
- //----------------------------------------------------------------------------------------
- void TDescriptor::GetNthItemData(SInt32 index, TUpdataDataReference& buffer, DescType desiredType, AEKeyword* key) const
- {
- AEKeyword ignoreKey;
-
- if(key == nil)
- key = &ignoreKey;
-
- //
- // We can "GetNthItem" on an item that is not of typeAEList
- // if the index is one; we do this by cloning ourself
- // (n.b. AERecords are also lists)
- //
- if((DescriptorType() != typeAEList) && (DescriptorType() != typeAERecord))
- {
- if(index != 1)
- FailErr(errAEIllegalIndex);
-
- *key = typeWildCard;
- this->GetDescriptorData(buffer);
- }
- else
- {
- DescType actualType;
- SInt32 actualSize = 0;
-
- FailErr(AEGetNthPtr(*this, index, desiredType, key, &actualType, buffer.Data(), buffer.MaxLength(), &actualSize));
- buffer.SetDataLength(actualSize);
- buffer.SetDataType(actualType);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AddItemToList:
- //
- // Add data to a descriptor list at a specified index, replacing any item already stored
- // at that position.
- //----------------------------------------------------------------------------------------
- void TDescriptor::AddItemToList(SInt32 index, const TDescriptor& data)
- {
- //
- // If the list is completely empty, just put the data directly into
- // this descriptor (don't make a list)
- //
- if(this->IsNullDescriptor())
- {
- this->SetDescriptorData(data);
- }
- else
- {
- //
- // If we're not a list yet, we'd better make ourselves one now.
- //
- if(this->DescriptorType() != typeAEList)
- this->CoerceToList();
- FailErr(AEPutDesc(*this, index, data));
- }
- } // TDescriptor::AddItemToList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AddItemToList:
- //
- // Add data to a descriptor list at the end of the list
- //----------------------------------------------------------------------------------------
- void TDescriptor::AddItemToList(const TDescriptor& data)
- {
- this->AddItemToList(0,data);
- } // TDescriptor::AddItemToList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AddItemToList:
- //----------------------------------------------------------------------------------------
- void TDescriptor::AddItemToList(SInt32 index, const TAbstractDataReference& data)
- {
- //
- // If the list is completely empty, we'd better make an empty list
- // (the type coercion from null to typeAEList probably works,
- // but I have not tested it yet; the following two lines may
- // be superfluous)
- //
- if(this->IsNullDescriptor())
- this->CreateList();
-
- //
- // If we're not a list yet, we'd better make ourselves one now.
- //
- if(this->DescriptorType() != typeAEList)
- this->CoerceInPlace(typeAEList);
-
- //
- // Put the data into the list
- //
- FailErr(AEPutPtr(*this,index,data.DataType(),data.Data(),data.DataLength()));
- } // TDescriptor::AddItemToList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AddItemToList:
- //----------------------------------------------------------------------------------------
- void TDescriptor::AddItemToList(const TAbstractDataReference& data)
- {
- this->AddItemToList(0,data);
- } // TDescriptor::AddItemToList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AppendList:
- //
- // Append a list onto the end of this one. The list passed in may be a null descriptor
- // or a single item as well as a list.
- //----------------------------------------------------------------------------------------
- void TDescriptor::AppendList(const TDescriptor& list)
- {
- OSErr err = noErr;
-
- //
- // Take no action if our input is null
- //
- if(list.IsNullDescriptor() == false)
- {
- //
- // If this descriptor is a null descriptor, then we just want
- // to copy the incoming list.
- //
- // In the past we did not do this check, which resulted in
- // the unfortunate side effect of converting a single-item
- // list into a single (non-list) descriptor whenever said
- // list was 'AppendList'ed into an empty list. While this
- // may be more efficient, it really hosed us over in the case
- // of GetData on the selection property, which is SUPPOSED
- // to return a single-item list (as opposed to a single
- // descriptor) if there is only one item in the list. (This
- // is quite different from most other objects, which are
- // supposed to return single descriptors instead of single-
- // item lists whenever there is only one object in the result.)
- //
- if(this->IsNullDescriptor())
- {
- this->SetDescriptorData(list);
- }
- //
- // Script: in the past we did not check to see
- // if the list was an AERecord; this was very
- // bad because appending mutliple records together
- // into a list didn't work correctly (we would
- // iterate over the record--which works--
- // and add the data without its key!).
- //
- // Actually, we'll be a bit more efficient and
- // test for non-lists instead
- //
- else if(list.DescriptorType() != typeAEList)
- this->AddItemToList(list);
- else
- {
- Try
- {
- for(TDescriptorIterator iter(list); iter.More(); iter.Next())
- {
- this->AddItemToList(iter.Current());
- }
- }
- Catch(err)
- {
- Throw(err);
- }
- }
- }
- } // TDescriptor::AppendList
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::AppendListAndDispose:
- //----------------------------------------------------------------------------------------
- void TDescriptor::AppendListAndDispose(TDescriptor& list)
- {
- if(this->IsNullDescriptor())
- {
- this->AdoptDescriptor(list);
- }
- else
- {
- this->AppendList(list);
- list.Dispose();
- }
- } // TDescriptor::AppendListAndDispose
-
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Record methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeAERecord
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeAERecord()
- {
- this->CreateList(kMakeAERecord);
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetDescriptorParameter:
- //
- // Get the ae descriptor from the event. If the desired type is not specified, it
- // defaults to typeWildCard
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::GetDescriptorParameter(AEKeyword key, DescType desiredType /*= typeWildCard*/) const
- {
- TDescriptor result;
-
- //
- // n.b. This object must be typeAERecord or typeAppleEvent, or this
- // call will fail. Other record-like descriptors (e.g. object specifiers)
- // cannot be passed to AEGetParamDesc.
- //
- FailErr(AEGetParamDesc(*this, key, desiredType, result));
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetParameterData:
- //----------------------------------------------------------------------------------------
- void TDescriptor::GetParameterData(AEKeyword key, TUpdataDataReference& buffer, DescType desiredType /*= typeWildCard*/) const
- {
- //
- // n.b. This object must be typeAERecord or typeAppleEvent, or this
- // call will fail. Other record-like descriptors (e.g. object specifiers)
- // cannot be passed to AEGetParamPtr.
- //
- DescType actualType;
- SInt32 actualSize;
- FailErr(AEGetParamPtr(*this, key, desiredType, &actualType, buffer.Data(), buffer.MaxLength(), &actualSize));
- buffer.SetDataLength(actualSize);
- buffer.SetDataType(actualType);
- } // TDescriptor::GetParameterData
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetBooleanParameter:
- //----------------------------------------------------------------------------------------
- Boolean TDescriptor::GetBooleanParameter(AEKeyword key) const
- {
- SInt32 result = 0;
-
- this->GetParameterData(key, TUpdataDataReference(typeBoolean, (char*)&result, sizeof(Boolean), sizeof(Boolean)), typeBoolean);
-
- return result;
- } // TDescriptor::GetBooleanParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetSInt32Parameter:
- //----------------------------------------------------------------------------------------
- SInt32 TDescriptor::GetSInt32Parameter(AEKeyword key) const
- {
- SInt32 result = 0;
-
- this->GetParameterData(key, TUpdataDataReference(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32)), typeSInt32);
-
- return result;
- } // TDescriptor::GetSInt32Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetUInt32Parameter:
- //----------------------------------------------------------------------------------------
- UInt32 TDescriptor::GetUInt32Parameter(AEKeyword key) const
- {
- UInt32 result = 0;
-
- this->GetParameterData(key, TUpdataDataReference(typeUInt32, (char*)&result, sizeof(UInt32), sizeof(UInt32)), typeUInt32);
-
- return result;
- } // TDescriptor::GetUInt32Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetSInt64Parameter:
- //----------------------------------------------------------------------------------------
- SInt64 TDescriptor::GetSInt64Parameter(AEKeyword key) const
- {
- SInt64 result;
-
- this->GetParameterData(key, TUpdataDataReference(typeSInt64, (char*)&result, sizeof(SInt64), sizeof(SInt64)), typeSInt64);
-
- return result;
- } // TDescriptor::GetSInt64Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetDescTypeParameter:
- //----------------------------------------------------------------------------------------
- DescType TDescriptor::GetDescTypeParameter(AEKeyword key, DescType expectedType /*= typeType*/) const
- {
- DescType result = 0;
-
- this->GetParameterData(key, TUpdataDataReference(expectedType, (char*)&result, sizeof(DescType), sizeof(DescType)), expectedType);
-
- return result;
- } // TDescriptor::GetDescTypeParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetPSNParameter:
- //----------------------------------------------------------------------------------------
- ProcessSerialNumber TDescriptor::GetPSNParameter(AEKeyword key) const
- {
- ProcessSerialNumber result;
-
- this->GetParameterData(key, TUpdataDataReference(typeProcessSerialNumber, (char*)&result, sizeof(ProcessSerialNumber), sizeof(ProcessSerialNumber)), typeProcessSerialNumber);
-
- return result;
- } // TDescriptor::GetPSNParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetOptionalParameter:
- // Like 'GetDescriptorParameter, but returns a null descriptor if the specified
- // parameter could not be extracted.
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::GetOptionalParameter(AEKeyword key, DescType desiredType /*= typeWildCard*/) const
- {
- TDescriptor result;
- OSErr err = noErr;
-
- //
- // It's probably not necessary to call ClearDescriptor if there is
- // an error, but we might as well be safe (paranoid?).
- //
- err = AEGetParamDesc(*this, key, desiredType, result);
- if(err != noErr)
- result.ClearDescriptor();
-
- return result;
- } // TDescriptor::GetOptionalParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetOptionalParameterData
- //----------------------------------------------------------------------------------------
- void TDescriptor::GetOptionalParameterData(AEKeyword key, TUpdataDataReference& buffer, DescType desiredType /*= typeWildCard*/) const
- {
- DescType actualType;
- SInt32 actualSize;
- if(AEGetParamPtr(*this, key, desiredType, &actualType, buffer.Data(), buffer.MaxLength(), &actualSize) == noErr)
- {
- buffer.SetDataLength(actualSize);
- buffer.SetDataType(actualType);
- }
- else
- {
- buffer.SetDataLength(0);
- buffer.SetDataType(typeNull);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetOptionalSInt32Parameter:
- //----------------------------------------------------------------------------------------
- SInt32 TDescriptor::GetOptionalSInt32Parameter(AEKeyword key, SInt32 defaultValue /*= 0*/) const
- {
- SInt32 result = defaultValue;
- TUpdataDataReference buffer(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32));
-
- this->GetOptionalParameterData(key, buffer, typeSInt32);
- if(buffer.DataType() == typeNull)
- result = defaultValue;
-
- return result;
- } // TDescriptor::GetOptionalSInt32Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutDescriptorParameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutDescriptorParameter(AEKeyword key, const TDescriptor& data)
- {
- FailErr(AEPutParamDesc(*this, key, data));
- } // TDescriptor::PutDescriptorParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutParameterData:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutParameterData(AEKeyword key, const TAbstractDataReference& data)
- {
- FailErr(AEPutParamPtr(*this, key, data.DataType(), data.Data(), data.DataLength()));
- } // TDescriptor::PutParameterData
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutBooleanParameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutBooleanParameter(AEKeyword key, const Boolean& data)
- {
- this->PutParameterData(key, TConstDataReference(typeBoolean, (Ptr)&data, sizeof(Boolean)));
- } // TDescriptor::PutBooleanParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutSInt32Parameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutSInt32Parameter(AEKeyword key, const SInt32& data)
- {
- this->PutParameterData(key, TConstDataReference(typeSInt32, (Ptr)&data, sizeof(SInt32)));
- } // TDescriptor::PutSInt32Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutUInt32Parameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutUInt32Parameter(AEKeyword key, const UInt32& data)
- {
- this->PutParameterData(key, TConstDataReference(typeUInt32, (Ptr)&data, sizeof(UInt32)));
- } // TDescriptor::PutUInt32Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutSInt64Parameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutSInt64Parameter(AEKeyword key, const SInt64& data)
- {
- this->PutParameterData(key, TConstDataReference(typeSInt64, (Ptr)&data, sizeof(SInt64)));
- } // TDescriptor::PutSInt64Parameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutDescTypeParameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutDescTypeParameter(AEKeyword key, const SInt32& data, DescType dataType /*= typeType*/)
- {
- this->PutParameterData(key, TConstDataReference(dataType, (Ptr)&data, sizeof(DescType)));
- } // TDescriptor::PutDescTypeParameter
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::PutPSNParameter:
- //----------------------------------------------------------------------------------------
- void TDescriptor::PutPSNParameter(AEKeyword key, const ProcessSerialNumber& psn)
- {
- this->PutParameterData(key, TConstDataReference(typeProcessSerialNumber, (Ptr)&psn, sizeof(ProcessSerialNumber)));
- } // TDescriptor::PutPSNParameter
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Object specifier methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetObjectSpecifierParameters:
- //----------------------------------------------------------------------------------------
- void TDescriptor::GetObjectSpecifierParameters(DescType& desiredClass, DescType& keyForm, TDescriptor* keyData, TDescriptor* containerDesc) const
- {
- TDescriptor thisAsRecord = this->Coerce(typeAERecord);
-
- //
- // Extract the desired class, the key form and the key data from
- // the object specifier
- //
- desiredClass = thisAsRecord.GetDescTypeParameter(keyAEDesiredClass);
- keyForm = thisAsRecord.GetDescTypeParameter(keyAEKeyForm, typeEnumeration);
- if(keyData != nil)
- *keyData = thisAsRecord.GetDescriptorParameter(keyAEKeyData);
- if(containerDesc != nil)
- *containerDesc = thisAsRecord.GetDescriptorParameter(keyAEContainer);
-
- thisAsRecord.Dispose();
- } // TDescriptor::GetObjectSpecifierParameters
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeObjectSpecifier:
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeObjectSpecifier(DescType desiredClass, TDescriptor& container, DescType keyForm, TDescriptor keyData, Boolean disposeInputs)
- {
- FailErr(CreateObjSpecifier(desiredClass,container,keyForm,keyData,disposeInputs,*this));
- } // TDescriptor::MakeObjectSpecifier
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeObjectSpecifierForProperty:
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeObjectSpecifierForProperty(DescType propertyIdentifier, TDescriptor& container, Boolean disposeInputs)
- {
- TDescriptor propertyIDDesc;
-
- propertyIDDesc.SetDescTypeData(propertyIdentifier);
- this->MakeObjectSpecifier(cProperty, container, formPropertyID, propertyIDDesc, disposeInputs);
- propertyIDDesc.Dispose();
- } // TDescriptor::MakeObjectSpecifierForProperty
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::SetDescriptorDataTypeObjectBeingExamined
- //----------------------------------------------------------------------------------------
- void TDescriptor::SetDescriptorDataTypeObjectBeingExamined()
- {
- //
- // 'objectBeingExamined' is a special object specifier that only
- // has meaning in the context of a comparison descriptor. Note that
- // we are copying zero bytes into the data handle of the
- // "object being examined" descriptor, so it doesn't matter what
- // address we use here. It's best to pass in a valid address, though,
- // as you can never tell if the AEM might decide to dereference the
- // pointer you give it, even if it doesn't need it.
- //
- this->SetDescriptorData(TConstDataReference(typeObjectBeingExamined,(Ptr)this, 0));
- } // TDescriptor::SetDescriptorDataTypeObjectBeingExamined
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeSpecifierForPropertyOfObjectBeingExamined:
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeSpecifierForPropertyOfObjectBeingExamined(DescType propertyIdentifier)
- {
- TDescriptor objectBeingExamined;
-
- //
- // 'objectBeingExamined' is a special object specifier that only
- // has meaning in the context of a comparison descriptor. Note that
- // we are copying zero bytes into the data handle of the
- // "object being examined" descriptor, so it doesn't matter what
- // address we use here. It's best to pass in a valid address, though,
- // as you can never tell if the AEM might decide to dereference the
- // pointer you give it, even if it doesn't need it.
- //
- objectBeingExamined.SetDescriptorDataTypeObjectBeingExamined();
-
- //
- // result is "propertyIdentifier of (object being examined)"
- //
- this->MakeObjectSpecifierForProperty(propertyIdentifier, objectBeingExamined, true);
- } // TDescriptor::MakeSpecifierForPropertyOfObjectBeingExamined
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeCompDescriptor:
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeCompDescriptor(DescType comparisonOperator, TDescriptor& comparitor, TDescriptor& compareWith, Boolean disposeInputs)
- {
- CreateCompDescriptor(comparisonOperator, comparitor, compareWith, disposeInputs, *this);
- } // TDescriptor::MakeCompDescriptor
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::MakeCompDescriptor:
- //----------------------------------------------------------------------------------------
- void TDescriptor::MakeCompDescriptor(DescType comparisonOperator, DescType propertyIdentifier, TDescriptor& compareWith, Boolean disposeInputs)
- {
- TDescriptor operand1;
-
- operand1.MakeSpecifierForPropertyOfObjectBeingExamined(propertyIdentifier);
-
- //
- // Make a compDescriptor of operand1 compared with (comparisonOperator) compareWith
- //
- CreateCompDescriptor(comparisonOperator, operand1, compareWith, disposeInputs, *this);
- operand1.Dispose();
- } // TDescriptor::MakeCompDescriptor
-
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Object support library
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- TDescriptor gErrorDescriptor;
- Boolean gInstalledErrorCallback = false;
-
- #ifdef GENERATINGCFM
- static RoutineDescriptor gGetErrorDescCallbackRD = BUILD_ROUTINE_DESCRIPTOR(uppOSLGetErrDescProcInfo, TDescriptor::GetErrorDesc);
- #endif
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Resolve:
- //----------------------------------------------------------------------------------------
- TTokenDescriptor TDescriptor::Resolve(const TAETransaction& t, TDescriptor* objectThatCausedError /*= nil*/) const
- {
- return TDescriptor::Resolve(t, fCallbackFlags, objectThatCausedError);
- } // TDescriptor::Resolve
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Resolve:
- //
- // Resolves a list of object specifiers into a list of tokens. A null descriptor will
- // resolve to a token to the null container.
- //
- // n.b. AEResolve will return an error if you pass it a null descriptor; this is why
- // we include 'magic' checking for null descriptors here.
- //----------------------------------------------------------------------------------------
- TTokenDescriptor TDescriptor::Resolve(const TAETransaction& t, SInt16 callbackFlags, TDescriptor* objectThatCausedError /*= nil*/) const
- {
- TTokenDescriptor resolvedToken;
- TTokenDescriptor intermediate;
-
- #if 0 //◊
- SInt32 startTime = TickCount();
- SInt32 durration = 0;
- #endif
-
- //
- // First: special checking for null descriptors
- //
- if(this->IsNullDescriptor())
- {
- resolvedToken = CreateNullContainerToken();
- }
- //
- // Next, process non-lists
- //
- else if(this->DescriptorType() != typeAEList)
- {
- //
- // If a pre-resolve proc was installed, then call it.
- //
- // This is where we take over from the OSL and resolve
- // object specifiers ourselves...
- //
- if(gPreResolveProc != nil)
- {
- resolvedToken = (*gPreResolveProc)(t, *this, objectThatCausedError);
- }
-
- //
- // If the pre-resolve proc did not resolve the token,
- // then call AEResolve
- //
- if(resolvedToken.IsNullDescriptor())
- {
- if(gInstalledErrorCallback == false)
- {
- #ifdef GENERATINGCFM
- AEInstallSpecialHandler(keyAEGetErrDescProc, (UniversalProcPtr)&gGetErrorDescCallbackRD, false);
- #else
- AEInstallSpecialHandler(keyAEGetErrDescProc, (UniversalProcPtr)TDescriptor::GetErrorDesc, false);
- #endif
-
- gInstalledErrorCallback = true;
- }
-
- OSErr resolveErr = AEResolve(*this, callbackFlags, resolvedToken);
- if((resolveErr) != (noErr && objectThatCausedError != nil))
- {
- objectThatCausedError->AdoptDescriptor(gErrorDescriptor);
- gErrorDescriptor.ClearDescriptor();
- }
- else
- gErrorDescriptor.Dispose();
- FailErr(resolveErr);
- }
- }
- //
- // If we have a list, try to resolve each element of the list in turn
- //
- else
- {
- OSErr err = noErr;
-
- Try
- {
- for(TDescriptorIterator iter(*this); iter.More(); iter.Next())
- {
- //
- // We do not want to dispose of the intermediate token descriptor
- // because its data is adopted by the 'result' token descriptor.
- //
- intermediate = iter.Current().Resolve(t, callbackFlags, objectThatCausedError);
- resolvedToken.AdoptToken(intermediate);
- intermediate.ClearDescriptor();
- }
- }
- Catch(err)
- {
- intermediate.DisposeToken();
- resolvedToken.DisposeToken();
- Throw(err);
- }
- }
-
- #if 0 //◊
- durration = TickCount() - startTime;
- #endif
-
- return resolvedToken;
- } // TDescriptor::Resolve
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::GetErrorDesc:
- //
- // Tell the Object support library where it can put a descriptor (an object specifier)
- // to the object that caused the resolution to fail.
- //----------------------------------------------------------------------------------------
- pascal OSErr TDescriptor::GetErrorDesc(TDescriptor** errorDescriptor)
- {
- *errorDescriptor = &gErrorDescriptor;
-
- return noErr;
- } // TDescriptor::GetErrorDesc
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Old methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::CoerceToStandardType:
- //
- // This method attempts to coerce its data into some form of standard type
- // (e.g. typeChar or typeLongInteger). It is really annoying that someone can
- // invent yet another data type that is coercable to text or as a long integer,
- // but we wouldn't have any way to know that such a coercion should be attempted.
- // typeMagnitude and typeEnumeration could throw us for a loop too.
- //
- // ••• In short, I really hate this routine, but I'm not sure what else to do about it.
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptor::CoerceToStandardType() const
- {
- TDescriptor result;
-
- switch(this->DescriptorType())
- {
- case typeAEText:
- case typeIntlText:
- case typeStyledText:
- {
- result = this->Coerce(typeChar);
- break;
- }
-
- case typeShortInteger:
- {
- result = this->Coerce(typeLongInteger);
- break;
- }
- }
-
- return result;
- } // TDescriptor::CoerceToStandardType
-
- #if BUILDING_PREEMPTIVE_CODE
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Lock
- //----------------------------------------------------------------------------------------
- SInt16 TDescriptor::Lock() const
- {
- return 0;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Unlock
- //----------------------------------------------------------------------------------------
- void TDescriptor::Unlock(SInt16 /*oldState*/) const
- {
- }
-
- #else
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Lock
- //----------------------------------------------------------------------------------------
- SInt16 TDescriptor::Lock() const
- {
- SInt16 result = 0;
-
- if(this->DataHandle() != nil)
- {
- result = HGetState(this->DataHandle());
- HLock(this->DataHandle());
- }
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptor::Unlock
- //----------------------------------------------------------------------------------------
- void TDescriptor::Unlock(SInt16 oldState) const
- {
- if(this->DataHandle())
- HSetState(this->DataHandle(), oldState);
- }
-
- #endif
-
- //========================================================================================
- // CLASS TAEvent
- //
- // AppleEvents are just like AERecords, but they can contain attributes as well as
- // parameters.
- //========================================================================================
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Event creation
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TAEvent::MakeAppleEvent:
- //----------------------------------------------------------------------------------------
- void TAEvent::MakeAppleEvent(AEEventClass eventClass, AEEventID eventID,
- const AEAddressDesc *target, SInt16 returnID, SInt32 transactionID)
- {
- FailErr(AECreateAppleEvent(eventClass, eventID,
- target, returnID, transactionID, *this));
- } // TAEvent::MakeAppleEvent
-
- //----------------------------------------------------------------------------------------
- // TAEvent::MakeAppleEvent:
- //----------------------------------------------------------------------------------------
- void TAEvent::MakeAppleEvent(AEEventClass eventClass, AEEventID eventID,
- const ProcessSerialNumber& psn, SInt16 returnID, SInt32 transactionID)
- {
- TDescriptor address;
- address.SetPSNData(psn);
-
- this->MakeAppleEvent(eventClass, eventID, (const AEAddressDesc *) &address, returnID, transactionID);
-
- address.Dispose();
- } // TAEvent::MakeAppleEvent
-
-
- #define kCheckAEM 0
- #define kDontUseSelfSend 1
- #define kSelfSendSafe 2
-
- SInt16 gCanUseSelfSend = kCheckAEM;
-
- //----------------------------------------------------------------------------------------
- // TAEvent::MakeEventAddressedToSelf:
- //----------------------------------------------------------------------------------------
- void TAEvent::MakeEventAddressedToSelf(AEEventClass eventClass, AEEventID eventID, SInt16 returnID, SInt32 transactionID)
- {
- ProcessSerialNumber current; // create psn for self
- current.highLongOfPSN = 0;
- current.lowLongOfPSN = kCurrentProcess;
-
- #if 0 // FOR_SYSTEM7_ONLY
- //
- // Old versions of the AEM leak memory if send-to-self is used
- //
- if(gCanUseSelfSend == kCheckAEM)
- {
- SInt32 aevtSelector = 0;
- OSErr err = Gestalt('evnt', &aevtSelector);
- gCanUseSelfSend = ((aevtSelector & 2) != 0) ? kSelfSendSafe : kDontUseSelfSend;
- }
-
- //
- // Don't make the self-addressed event unless it is safe to do so
- //
- if(gCanUseSelfSend == kSelfSendSafe)
- {
- this->MakeAppleEvent(eventClass, eventID, current, returnID, transactionID);
- }
- else
- FailErr(errAEEventNotHandled);
- #else
- this->MakeAppleEvent(eventClass, eventID, current, returnID, transactionID);
- #endif
- } // TAEvent::MakeEventAddressedToSelf
-
- //----------------------------------------------------------------------------------------
- // TAEvent::MakeEventAddressedToSystem:
- //----------------------------------------------------------------------------------------
- void TAEvent::MakeEventAddressedToSystem(AEEventClass eventClass, AEEventID eventID, SInt16 returnID, SInt32 transactionID)
- {
- ProcessSerialNumber systemPSN; // create psn for the System
- systemPSN.highLongOfPSN = 0;
- systemPSN.lowLongOfPSN = kSystemProcess;
-
- this->MakeAppleEvent(eventClass, eventID, systemPSN, returnID, transactionID);
- } // TAEvent::MakeEventAddressedToSystem
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Attribute access
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetDescriptorAttribute:
- //
- // Get the ae descriptor from the event. If the desired type is not specified, it
- // defaults to typeWildCard
- //----------------------------------------------------------------------------------------
- TDescriptor TAEvent::GetDescriptorAttribute(AEKeyword key, DescType desiredType /*= typeWildCard*/) const
- {
- TDescriptor result;
-
- //
- // n.b. This object must be typeAERecord or typeAppleEvent, or this
- // call will fail. Other record-like descriptors (e.g. object specifiers)
- // cannot be passed to AEGetParamDesc.
- //
- FailErr(AEGetAttributeDesc(*this, key, desiredType, result));
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetAttributeData:
- //----------------------------------------------------------------------------------------
- void TAEvent::GetAttributeData(AEKeyword key, TUpdataDataReference& buffer, DescType desiredType /*= typeWildCard*/) const
- {
- //
- // n.b. This object must be typeAERecord or typeAppleEvent, or this
- // call will fail. Other record-like descriptors (e.g. object specifiers)
- // cannot be passed to AEGetAttributePtr.
- //
- DescType actualType;
- SInt32 actualSize;
- FailErr(AEGetAttributePtr(*this, key, desiredType, &actualType, buffer.Data(), buffer.MaxLength(), &actualSize));
- buffer.SetDataLength(actualSize);
- buffer.SetDataType(actualType);
- } // TAEvent::GetAttributeData
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetBooleanAttribute:
- //----------------------------------------------------------------------------------------
- Boolean TAEvent::GetBooleanAttribute(AEKeyword key) const
- {
- SInt32 result = 0;
-
- this->GetAttributeData(key, TUpdataDataReference(typeBoolean, (char*)&result, sizeof(Boolean), sizeof(Boolean)), typeBoolean);
-
- return result;
- } // TAEvent::GetBooleanAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetSInt32Attribute:
- //----------------------------------------------------------------------------------------
- SInt32 TAEvent::GetSInt32Attribute(AEKeyword key) const
- {
- SInt32 result = 0;
-
- this->GetAttributeData(key, TUpdataDataReference(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32)), typeSInt32);
-
- return result;
- } // TAEvent::GetSInt32Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetUInt32Attribute:
- //----------------------------------------------------------------------------------------
- UInt32 TAEvent::GetUInt32Attribute(AEKeyword key) const
- {
- UInt32 result = 0;
-
- this->GetAttributeData(key, TUpdataDataReference(typeUInt32, (char*)&result, sizeof(UInt32), sizeof(UInt32)), typeUInt32);
-
- return result;
- } // TAEvent::GetUInt32Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetSInt64Attribute:
- //----------------------------------------------------------------------------------------
- SInt64 TAEvent::GetSInt64Attribute(AEKeyword key) const
- {
- SInt64 result;
-
- this->GetAttributeData(key, TUpdataDataReference(typeSInt64, (char*)&result, sizeof(SInt64), sizeof(SInt64)), typeSInt64);
-
- return result;
- } // TAEvent::GetSInt64Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetDescTypeAttribute:
- //----------------------------------------------------------------------------------------
- DescType TAEvent::GetDescTypeAttribute(AEKeyword key, DescType expectedType /*= typeType*/) const
- {
- DescType result = 0;
-
- this->GetAttributeData(key, TUpdataDataReference(expectedType, (char*)&result, sizeof(DescType), sizeof(DescType)), expectedType);
-
- return result;
- } // TAEvent::GetDescTypeAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetPSNAttribute:
- //----------------------------------------------------------------------------------------
- ProcessSerialNumber TAEvent::GetPSNAttribute(AEKeyword key) const
- {
- ProcessSerialNumber result;
-
- this->GetAttributeData(key, TUpdataDataReference(typeProcessSerialNumber, (char*)&result, sizeof(ProcessSerialNumber), sizeof(ProcessSerialNumber)), typeProcessSerialNumber);
-
- return result;
- } // TAEvent::GetPSNAttribute
-
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetOptionalAttribute:
- // Like 'GetDescriptorAttribute, but returns a null descriptor if the specified
- // Attribute could not be extracted.
- //----------------------------------------------------------------------------------------
- TDescriptor TAEvent::GetOptionalAttribute(AEKeyword key, DescType desiredType /*= typeWildCard*/) const
- {
- TDescriptor result;
- OSErr err = noErr;
-
- //
- // It's probably not necessary to call ClearDescriptor if there is
- // an error, but we might as well be safe (paranoid?).
- //
- err = AEGetAttributeDesc(*this, key, desiredType, result);
- if(err != noErr)
- result.ClearDescriptor();
-
- return result;
- } // TAEvent::GetOptionalAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetOptionalAttributeData
- //----------------------------------------------------------------------------------------
- void TAEvent::GetOptionalAttributeData(AEKeyword key, TUpdataDataReference& buffer, DescType desiredType /*= typeWildCard*/) const
- {
- DescType actualType;
- SInt32 actualSize;
- if(AEGetAttributePtr(*this, key, desiredType, &actualType, buffer.Data(), buffer.MaxLength(), &actualSize) == noErr)
- {
- buffer.SetDataLength(actualSize);
- buffer.SetDataType(actualType);
- }
- else
- {
- buffer.SetDataLength(0);
- buffer.SetDataType(typeNull);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TAEvent::GetOptionalSInt32Attribute:
- //----------------------------------------------------------------------------------------
- SInt32 TAEvent::GetOptionalSInt32Attribute(AEKeyword key, SInt32 defaultValue /*= 0*/) const
- {
- SInt32 result = defaultValue;
- TUpdataDataReference buffer(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32));
-
- this->GetOptionalAttributeData(key, buffer, typeSInt32);
- if(buffer.DataType() == typeNull)
- result = defaultValue;
-
- return result;
- } // TAEvent::GetOptionalSInt32Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutDescriptorAttribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutDescriptorAttribute(AEKeyword key, const TDescriptor& data)
- {
- FailErr(AEPutAttributeDesc(*this, key, data));
- } // TAEvent::PutDescriptorAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutAttributeData:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutAttributeData(AEKeyword key, const TAbstractDataReference& data)
- {
- FailErr(AEPutAttributePtr(*this, key, data.DataType(), data.Data(), data.DataLength()));
- } // TAEvent::PutAttributeData
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutBooleanAttribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutBooleanAttribute(AEKeyword key, const Boolean& data)
- {
- this->PutAttributeData(key, TConstDataReference(typeBoolean, (Ptr)&data, sizeof(Boolean)));
- } // TAEvent::PutBooleanAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutSInt32Attribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutSInt32Attribute(AEKeyword key, const SInt32& data)
- {
- this->PutAttributeData(key, TConstDataReference(typeSInt32, (Ptr)&data, sizeof(SInt32)));
- } // TAEvent::PutSInt32Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutUInt32Attribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutUInt32Attribute(AEKeyword key, const UInt32& data)
- {
- this->PutAttributeData(key, TConstDataReference(typeUInt32, (Ptr)&data, sizeof(UInt32)));
- } // TAEvent::PutUInt32Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutSInt64Attribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutSInt64Attribute(AEKeyword key, const SInt64& data)
- {
- this->PutAttributeData(key, TConstDataReference(typeSInt64, (Ptr)&data, sizeof(SInt64)));
- } // TAEvent::PutSInt64Attribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutDescTypeAttribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutDescTypeAttribute(AEKeyword key, const SInt32& data, DescType dataType /*= typeType*/)
- {
- this->PutAttributeData(key, TConstDataReference(dataType, (Ptr)&data, sizeof(DescType)));
- } // TAEvent::PutDescTypeAttribute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutPSNAttribute:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutPSNAttribute(AEKeyword key, const ProcessSerialNumber& psn)
- {
- this->PutAttributeData(key, TConstDataReference(typeProcessSerialNumber, (Ptr)&psn, sizeof(ProcessSerialNumber)));
- } // TAEvent::PutPSNAttribute
-
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Special descriptor access
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutOptionalDescriptorParameter:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutOptionalDescriptorParameter(AEKeyword key, const TDescriptor& data)
- {
- this->PutDescriptorParameter(key, data);
- this->SpecifyThatParameterIsOptional(key);
- } // TAEvent::PutOptionalDescriptorParameter
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutOptionalParameterData:
- //----------------------------------------------------------------------------------------
- void TAEvent::PutOptionalParameterData(AEKeyword key, const TAbstractDataReference& data)
- {
- this->PutParameterData(key, data);
- this->SpecifyThatParameterIsOptional(key);
- }
-
- //----------------------------------------------------------------------------------------
- // TAEvent::PutResult:
- //
- // Put the provided descriptor into the result parameter of this event. If the data
- // is a null descriptor, then put in an empty list instead.
- //----------------------------------------------------------------------------------------
- void TAEvent::PutResult(const TDescriptor& data)
- {
- OSErr err = noErr;
-
- //
- // If this is a null descriptor, it means that the client
- // doesn't care about the reply, so ignore the result.
- //
- if(this->IsNullDescriptor() == false)
- {
- //
- // If there's nothing in the data, then insert an empty list.
- //
- if(data.IsNullDescriptor())
- {
- TDescriptor emptyList;
-
- Try
- {
- emptyList.CreateList();
- this->PutDescriptorParameter(keyAEResult, emptyList);
- emptyList.Dispose();
- }
- Catch(err)
- {
- emptyList.Dispose();
- Throw(err);
- }
- }
- else
- {
- this->PutDescriptorParameter(keyAEResult,data);
- }
- }
- } // TAEvent::PutResult
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Special-use methods
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-
- //----------------------------------------------------------------------------------------
- // TAEvent::CanInteractWithUser:
- //----------------------------------------------------------------------------------------
- Boolean TAEvent::CanInteractWithUser() const
- {
- Boolean canInteract = true;
-
- TDescriptor interactDesc = this->GetOptionalAttribute(keyInteractLevelAttr, typeEnumerated);
- if((interactDesc.IsNullDescriptor()) || (interactDesc.GetDescTypeData(typeEnumeration) != 'cans'))
- canInteract = false;
- interactDesc.Dispose();
-
- return canInteract;
- } // TAEvent::CanInteractWithUser
-
- //----------------------------------------------------------------------------------------
- // TAEvent::ResetTimer:
- //
- // Note: requires that this event be a 'reply' event passed to one of our event
- // handlers by the AppleEvent manager
- //----------------------------------------------------------------------------------------
- void TAEvent::ResetTimer()
- {
- FailErr(AEResetTimer(*this));
- } // TAEvent::ResetTimer
-
- //----------------------------------------------------------------------------------------
- // TAEvent::SpecifyThatParameterIsOptional:
- //----------------------------------------------------------------------------------------
- void TAEvent::SpecifyThatParameterIsOptional(AEKeyword theOptionalKeyword)
- {
- TDescriptor optionalKeywordsList;
- OSErr err = noErr;
-
- Try
- {
- //
- // Try to fetch the keyOptionalKeywordAttr; if it does, then just
- // add one more element to the list that is already inside the event.
- //
- optionalKeywordsList = this->GetOptionalAttribute(keyOptionalKeywordAttr);
- if(optionalKeywordsList.IsNullDescriptor())
- optionalKeywordsList.CreateList();
- optionalKeywordsList.AddItemToList(TConstDataReference(typeKeyword, (Ptr)&theOptionalKeyword, sizeof(AEKeyword)));
- this->PutDescriptorAttribute(keyOptionalKeywordAttr, optionalKeywordsList);
- optionalKeywordsList.Dispose();
- }
- Catch(err)
- {
- optionalKeywordsList.Dispose();
-
- Throw(err);
- }
- } // TAEvent::SpecifyThatParameterIsOptional
-
-
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- //:: Send and receive
- //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
- //----------------------------------------------------------------------------------------
- // TAEvent::Send:
- //----------------------------------------------------------------------------------------
- void TAEvent::Send( TAEvent* reply,
- AESendMode sendMode,
- AESendPriority sendPriority,
- SInt32 timeOutInTicks,
- AEIdleUPP idleProc,
- AEFilterUPP filterProc)
- {
- OSErr err = noErr;
-
- err = AESend(*this, *reply, sendMode, sendPriority, timeOutInTicks, idleProc, filterProc);
- if((err != errAETimeout) || (timeOutInTicks != 0))
- FailErr(err);
- } // TAEvent::Send
-
- void TAEvent::SendNoReply()
- {
- TAEvent reply;
-
- this->Send(&reply, kAENoReply);
- }
-
- #define kAEDontExecute 0x2000 // for SendMode, when you just want an event recorded, not executed
-
- //----------------------------------------------------------------------------------------
- // TAEvent::SendNoExecute:
- //
- // This routine sends the event with the 'kAEDontExecute' bit set, so that the
- // event will be recorded, but the recipient will not execute it. The event is
- // also sent 'no reply', since it does not make sense to expect a result from
- // a command that is not actually executed.
- //----------------------------------------------------------------------------------------
- void TAEvent::SendNoExecute()
- {
- //
- // The reply isn't actuall filled in due to the kAENoReply flag
- //
- TAEvent reply;
- Send(&reply, kAENoReply+kAEDontExecute);
- } // TAEvent::SendNoExecute
-
- //----------------------------------------------------------------------------------------
- // TAEvent::SuspendTheCurrentEvent:
- //----------------------------------------------------------------------------------------
- void TAEvent::SuspendTheCurrentEvent()
- {
- FailErr(AESuspendTheCurrentEvent(*this));
- } // TAEvent::SuspendTheCurrentEvent
-
- //----------------------------------------------------------------------------------------
- // TAEvent::ResumeTheCurrentEvent:
- //----------------------------------------------------------------------------------------
- void TAEvent::ResumeTheCurrentEvent(TAEvent* reply, AEEventHandlerUPP dispatcher, SInt32 refCon)
- {
- FailErr(AEResumeTheCurrentEvent(*this, *reply, dispatcher, refCon));
- } // TAEvent::ResumeTheCurrentEvent
-
- //----------------------------------------------------------------------------------------
- // TAEvent::SetTheCurrentEvent:
- //----------------------------------------------------------------------------------------
- void TAEvent::SetTheCurrentEvent()
- {
- FailErr(AESetTheCurrentEvent(*this));
- } // TAEvent::SetTheCurrentEvent
-
-
- //========================================================================================
- // CLASS TDescriptorIterator
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::~TDescriptorIterator
- //----------------------------------------------------------------------------------------
- TDescriptorIterator::~TDescriptorIterator()
- {
- fCurrent.Dispose();
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::Reset
- //----------------------------------------------------------------------------------------
- void TDescriptorIterator::Reset(Boolean iterateBackwards /*= false*/)
- {
- fCurrent.Dispose();
- fIterateBackwards = iterateBackwards;
- if(fIterateBackwards)
- fCurrentIndex = fCachedCount;
- else
- fCurrentIndex = 1;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::More
- //----------------------------------------------------------------------------------------
- Boolean TDescriptorIterator::More() const
- {
- return ((fCurrentIndex > 0) && (fCurrentIndex <= fCachedCount));
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::Next
- //----------------------------------------------------------------------------------------
- void TDescriptorIterator::Next()
- {
- if(this->More())
- {
- if(fIterateBackwards)
- --fCurrentIndex;
- else
- ++fCurrentIndex;
-
- fCurrent.Dispose();
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::Current
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptorIterator::Current() const
- {
- if(this->More())
- ((TDescriptorIterator*)this)->fCurrent = fDescriptorList.GetNthItem(fCurrentIndex);
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::OrphanCurrent
- //----------------------------------------------------------------------------------------
- TDescriptor TDescriptorIterator::OrphanCurrent()
- {
- TDescriptor result = this->Current();
- fCurrent.ClearDescriptor();
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::CurrentKeyword
- //----------------------------------------------------------------------------------------
- AEKeyword TDescriptorIterator::CurrentKeyword() const
- {
- UInt32 unusedBufferspace;
- AEKeyword resultKeyword = typeWildCard;
-
- this->GetCurrentItemData(TUpdataDataReference(typeWildCard, (char*)&unusedBufferspace, 0, 0), typeWildCard, &resultKeyword);
-
- return resultKeyword;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentItemData
- //----------------------------------------------------------------------------------------
- void TDescriptorIterator::GetCurrentItemData(TUpdataDataReference& buffer, DescType desiredType /*= typeWildCard*/, AEKeyword* key /*= nil*/) const
- {
- if(this->More())
- {
- fDescriptorList.GetNthItemData(fCurrentIndex, buffer, desiredType, key);
- }
- else
- {
- buffer.SetDataType(typeNull);
- buffer.SetDataLength(0);
- if(key != nil)
- *key = typeNull;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentBooleanData
- //----------------------------------------------------------------------------------------
- Boolean TDescriptorIterator::GetCurrentBooleanData() const
- {
- Boolean result;
-
- this->GetCurrentItemData(TUpdataDataReference(typeBoolean, (char*)&result, sizeof(Boolean), sizeof(Boolean)), typeBoolean);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentSInt32Data
- //----------------------------------------------------------------------------------------
- SInt32 TDescriptorIterator::GetCurrentSInt32Data() const
- {
- SInt32 result;
-
- this->GetCurrentItemData(TUpdataDataReference(typeSInt32, (char*)&result, sizeof(SInt32), sizeof(SInt32)), typeSInt32);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentUInt32Data
- //----------------------------------------------------------------------------------------
- UInt32 TDescriptorIterator::GetCurrentUInt32Data() const
- {
- UInt32 result;
-
- this->GetCurrentItemData(TUpdataDataReference(typeUInt32, (char*)&result, sizeof(UInt32), sizeof(UInt32)), typeUInt32);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentSInt64Data
- //----------------------------------------------------------------------------------------
- SInt64 TDescriptorIterator::GetCurrentSInt64Data() const
- {
- SInt64 result;
-
- this->GetCurrentItemData(TUpdataDataReference(typeSInt64, (char*)&result, sizeof(SInt64), sizeof(SInt64)), typeSInt64);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // TDescriptorIterator::GetCurrentDescTypeData
- //----------------------------------------------------------------------------------------
- DescType TDescriptorIterator::GetCurrentDescTypeData(DescType expectedType /*= typeType*/) const
- {
- DescType result;
-
- this->GetCurrentItemData(TUpdataDataReference(expectedType, (char*)&result, sizeof(DescType), sizeof(DescType)), expectedType);
-
- return result;
- }
-
- //========================================================================================
- // CLASS TTokenDescriptor
- //
- // The class TTokenDescriptor represents descriptors returned by AEResolve
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // TTokenDescriptor::DisposeToken:
- //
- // It is very important that token descriptors be disposed of by AEDisposeToken,
- // _not_ AEDisposeDesc.
- //----------------------------------------------------------------------------------------
- void TTokenDescriptor::DisposeToken()
- {
- AEDisposeToken(*this); // Should fail on error? Probably not.
- } // TTokenDescriptor::DisposeToken
-
-
- //----------------------------------------------------------------------------------------
- // TTokenDescriptor::TokenObject:
- //
- // Return the object stored inside the token descriptor
- //----------------------------------------------------------------------------------------
- TAbstractScriptableObject* TTokenDescriptor::TokenObject()
- {
- TAbstractScriptableObject* tokenObject = nil;
- #if 0
- Handle tokenHandle = this->DataHandle();
-
- if(this->DescriptorType() == typeTokenObject)
- {
- tokenObject = (TAbstractScriptableObject*) tokenHandle;
- }
- else
- #endif
- if(this->DescriptorType() == typeTokenInHandle)
- {
- //
- // tokenHandle is a handle that contains a TTokenObject*,
- // so it is a pointer to a pointer to a TTokenObject* (wow).
- // This code is never used if your application supports marking.
- //
- #if 0
- tokenObject = ** ((TAbstractScriptableObject***) tokenHandle);
- #endif
- this->GetDescriptorData(TUpdataDataReference(typeTokenInHandle, (Ptr)&tokenObject, sizeof(Ptr), sizeof(Ptr)));
- }
- else if((this->DescriptorType() == typeAEList) && (gMergeTokensProc != nil))
- {
- //
- // This will only happen if the OSL merges tokens into
- // an AEList for you, which will only happen if your
- // application does not support marking.
- //
- for(TDescriptorIterator iter(*this); iter.More(); iter.Next())
- {
- TTokenDescriptor tokenDesc = iter.Current();
- TAbstractScriptableObject* intermediateObject = tokenDesc.TokenObject();
- if(tokenObject == nil)
- tokenObject = intermediateObject;
- else
- tokenObject = (*gMergeTokensProc)(tokenObject, intermediateObject);
- }
- }
-
- if(tokenObject == nil)
- {
- //
- // ••• What error code should we fail with here?
- //
- FailErr(errAENoSuchObject);
- }
-
- return tokenObject;
- } // TTokenDescriptor::TokenObject
-
-
- //----------------------------------------------------------------------------------------
- // TTokenDescriptor::AdoptToken:
- //
- // IMPORTANT: ADOPTS THE TOKEN PASSED TO IT
- //----------------------------------------------------------------------------------------
- void TTokenDescriptor::AdoptToken(TTokenDescriptor& tokenDescriptor)
- {
- //
- // Don't adopt the new token if it is empty
- //
- if(tokenDescriptor.IsNullDescriptor() == false)
- {
- //
- // If this descriptor is empty, it is easy to adopt the new token
- //
- if( this->IsNullDescriptor() )
- {
- AdoptDescriptor(tokenDescriptor);
- }
- //
- // If the token being adopted is a list, then append it to us
- // (we really want to avoid making AELists of AELists).
- //
- else if(tokenDescriptor.DescriptorType() == typeAEList)
- {
- //
- // We don't expect to get here any more
- //
- ASSERTPRINT(false, ("Got an AEList in TTokenDescriptor::AdoptToken!"));
- }
- else
- {
- TAbstractScriptableObject* tokenObject = tokenDescriptor.TokenObject();
- this->AdoptToken(tokenObject);
-
- //
- // n.b. 'Dispose', not 'DisposeToken'. The token that
- // was formerly contained in tokenDescriptor is now referenced
- // in 'this' token descriptor, so it would be a bad idea to
- // delete it.
- //
- tokenDescriptor.Dispose();
- }
- }
- } // TTokenDescriptor::AdoptToken
-
- // Boolean gCheatAndInlineToken = false;
-
- //----------------------------------------------------------------------------------------
- // TTokenDescriptor::AdoptToken:
- //----------------------------------------------------------------------------------------
- void TTokenDescriptor::AdoptToken(TAbstractScriptableObject* tokenObject)
- {
- //
- // Don't adopt the new token if it is not a valid object
- //
- if(tokenObject != nil)
- {
- //
- // If this descriptor is empty, then put the token object
- // into this token. If marking is supported, then the
- // token pointer may be placed into the token directly; if
- // marking is not supported, then we must create a handle
- // to hold the token.
- //
- if(this->IsNullDescriptor() )
- {
- #if 0
- // if((fCallbackFlags & kAEIDoMarking) != 0)
- if(gCheatAndInlineToken)
- this->AdoptHandle(typeTokenObject, (Handle)tokenObject);
- else
- #endif
- {
- this->SetDescriptorData(TConstDataReference(typeTokenInHandle, (Ptr)&tokenObject, sizeof(Ptr)));
- }
- }
- //
- // If there is already something here, then we need
- // to somehow merge the two tokens together.
- // Usually, we want to create a mark token
- // to do the merge. However, MoreAEM does not depend
- // on files such as MarkToken.h which are outside of
- // the Blue folder. Therefore, we call a callback proc
- // to fill in the mark token. The callback proc is
- // installed in InitializeScriptability.
- //
- else
- {
- if(gMergeTokensProc == nil)
- FailErr(errAEEventNotHandled);
-
- //
- // The MergeTokensProc takes two TAbstractScriptableObject*'s
- // and merges them into another TAbstractScriptableObject*
- // (which adopts the two original tokens).
- //
- TAbstractScriptableObject* mergedTokens = (*gMergeTokensProc)(this->TokenObject(), tokenObject);
- this->ClearDescriptor();
- this->AdoptToken(mergedTokens);
- }
- }
- } // TTokenDescriptor::AdoptToken
-
- Boolean TDescriptorDataReference::DirectlyReadable() const
- {
- return true;
- }
-
-
- Boolean TDescriptorDataReference::Writable() const
- {
- return true;
- }
-
- Boolean TDescriptorDataReference::Resizable() const
- {
- return true;
- }
-
- SInt32 TDescriptorDataReference::DataType() const
- {
- return fDescriptor.DescriptorType();
- }
-
- SInt32 TDescriptorDataReference::DataLength() const
- {
- return fDescriptor.DataSize();
- }
-
- SInt32 TDescriptorDataReference::MaxLength() const
- {
- return 0x7FFFFFFF;
- }
-
- SInt32 TDescriptorDataReference::CopyTo(char* destination, SInt32 maxBytesToCopy) const
- {
- fDescriptor.GetDescriptorData(TUpdataDataReference(typeWildCard, destination, 0, maxBytesToCopy));
- return this->DataLength();
- }
-
- Boolean TDescriptorDataReference::CopyFrom(const TAbstractDataReference& source, Boolean)
- {
- fDescriptor.SetDescriptorData(source);
- return true;
- }
-
- const char* TDescriptorDataReference::Data() const
- {
- char* inlineData = nil;
-
- inlineData = *fDescriptor.DataHandle();
-
- return inlineData;
- }
-
-
- #if 0
-
- //========================================================================================
- // CLASS TDescriptorLoop
- //
- // The class TDescriptorLoop is used by the macro FOREACHDESCRIPTOR. Note that the
- // descriptor returned by "Next" is a copy that must be disposed of by the programmer.
- //
- // We could have TDescriptorLoop keep track of the descriptor it created, and have it
- // dispose it when done. This would necessitate an 'orphan' method, though, in case
- // someone else wanted to adopt the descriptor.
- //========================================================================================
-
- #ifdef notinlineconst
- //----------------------------------------------------------------------------------------
- // TDescriptorLoop::TDescriptorLoop:
- //----------------------------------------------------------------------------------------
- TDescriptorLoop::TDescriptorLoop(const TDescriptor* dl)
- {
- fDescriptorList = dl;
- fIndex = 0;
- fCount = dl->CountItems();
- } // TDescriptorLoop::TDescriptorLoop
- #endif
- //----------------------------------------------------------------------------------------
- // TDescriptorLoop::Next:
- //
- // If 'key' is not nil, it is filled in with the keyword from the i'th item of the
- // list (if the list is a record)
- //----------------------------------------------------------------------------------------
- Boolean TDescriptorLoop::Next(TDescriptor& d, AEKeyword* key)
- {
- Boolean moreToDo = false;
-
- //
- // Set up on the first time through the loop
- //
- if(fIndex == 0)
- {
- fCount = fDescriptorList->CountItems();
- if(d.IsNullDescriptor() == false)
- {
- ASSERTPRINT(false, ("TDescriptorLoop::Next: 'd' was not null on first iteration!"));
- FailErr(errAEEventFailed);
- }
- }
-
- //
- // Advance to the next item in the list...
- //
- fIndex++;
-
- //
- // Dispose of the 'd' from last time through the loop
- //
- d.Dispose();
-
- //
- // Are there still items in the list?
- //
- if (fIndex <= fCount)
- {
- //
- // At this point, we could check to see if 'fDescriptorList' actually
- // points to something that is _not_ a list; if so, we coule return a
- // _reference_ to the single object, and set a field that indicates that
- // 'd' is a reference, and should not be disposed next time through the
- // loop. The reason we do not do this is that 'd' will be disposed by
- // the client code if there is a failure, and there is no good way for
- // the client to know if d is a reference or not. We could remember
- // what 'd' was and clean it up in our destructor, but failures can
- // cause our TDescriptorLoop object to be orphaned without ever being
- // destructed.
- //
- d = fDescriptorList->GetNthItem(fIndex, typeWildCard, key);
-
- moreToDo = true;
- }
- //
- // No more items, clean up
- //
- else
- {
- if(key != nil)
- *key = typeNull;
- d.ClearDescriptor();
- }
-
- return moreToDo;
- } // TDescriptorLoop::Next
-
- #endif
-
-
-
- #pragma segment CFrontCruft
-